package com.luoqiz.security.config.oauth;

import com.luoqiz.common.constant.ResponseCodeConstant;
import com.luoqiz.common.httpEntity.HttpResponseService;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.oauth2.common.DefaultThrowableAnalyzer;
import org.springframework.security.oauth2.common.exceptions.OAuth2Exception;
import org.springframework.security.oauth2.provider.error.WebResponseExceptionTranslator;
import org.springframework.security.web.util.ThrowableAnalyzer;
import org.springframework.stereotype.Component;
import org.springframework.web.HttpRequestMethodNotSupportedException;

@Component("bootWebResponseExceptionTranslator")
public class BootOAuth2WebResponseExceptionTranslator implements WebResponseExceptionTranslator {

    private ThrowableAnalyzer throwableAnalyzer = new DefaultThrowableAnalyzer();

    @Override
    public ResponseEntity translate(Exception e) throws Exception {
        Throwable[] causeChain = throwableAnalyzer.determineCauseChain(e);
        Exception ase = (OAuth2Exception) throwableAnalyzer.getFirstThrowableOfType(OAuth2Exception.class, causeChain);

        if (ase != null) {
            return ResponseEntity.ok(HttpResponseService.setError(
                    ((OAuth2Exception) ase).getHttpErrorCode(), ((OAuth2Exception) ase).getOAuth2ErrorCode(), ((OAuth2Exception) ase).getLocalizedMessage()));
        }

        ase = (AuthenticationException) throwableAnalyzer.getFirstThrowableOfType(AuthenticationException.class,
                causeChain);
        if (ase != null) {
            return ResponseEntity.ok(HttpResponseService.setError(
                    ResponseCodeConstant.HTTP_RES_CODE_401, "unauthorized", ResponseCodeConstant.HTTP_RES_CODE_401_VALUE));
        }

        ase = (AccessDeniedException) throwableAnalyzer
                .getFirstThrowableOfType(AccessDeniedException.class, causeChain);
        if (ase instanceof AccessDeniedException) {
            return ResponseEntity.ok(HttpResponseService.setError(
                    ResponseCodeConstant.HTTP_RES_CODE_403, "access_denied", ResponseCodeConstant.HTTP_RES_CODE_403_VALUE));
        }

        ase = (HttpRequestMethodNotSupportedException) throwableAnalyzer.getFirstThrowableOfType(
                HttpRequestMethodNotSupportedException.class, causeChain);
        if (ase instanceof HttpRequestMethodNotSupportedException) {
            return ResponseEntity.ok(HttpResponseService.setError(
                    ResponseCodeConstant.HTTP_RES_CODE_405, "method_not_allowed", ResponseCodeConstant.HTTP_RES_CODE_405_VALUE));
        }
        return ResponseEntity.ok(HttpResponseService.setError(
                ResponseCodeConstant.HTTP_RES_CODE_500, "server_error", ResponseCodeConstant.HTTP_RES_CODE_500_VALUE));

    }

}